package com.nulldev.util.networking.async2.udp;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Async2UDPServer {
	private final String fName;
	private final String fDescription;
	private final ArrayList<UDPListener> fListeners = new ArrayList<UDPListener>();
	@SuppressWarnings("rawtypes")
	private final ArrayBlockingQueue fThreadPoolQueue = new ArrayBlockingQueue(50000);
	public final ThreadPoolExecutor fThreadPool;

	@SuppressWarnings("unchecked")
	public Async2UDPServer(final String name, final String description, final int corePoolSize, final int maximumPoolSize) {
		this.fName = name;
		this.fDescription = description;
		this.fThreadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 2, TimeUnit.SECONDS, this.fThreadPoolQueue);
	}

	public UDPListener addListener(final String name, final InetAddress ipAddress, final int port, final int readBufferSize, final int readDataTimeOut) {
		final UDPListener listener = new UDPListener(this, name, ipAddress, port, readBufferSize, readDataTimeOut);
		this.fListeners.add(listener);
		return listener;
	}

	public void removeListener(final String name) {
		for (int i = 0; i < this.fListeners.size(); i++) {
			if (((UDPListener) this.fListeners.get(i)).getName().equals(name)) {
				((UDPListener) this.fListeners.get(i)).stop();
				this.fListeners.remove(i);
				break;
			}
		}
	}

	public void sendData(final DatagramPacket packet) {
		for (int i = 0; i < this.fListeners.size(); i++) {
			((UDPListener) this.fListeners.get(i)).sendData(packet);
		}
	}

	public void onDataReceive(final UDPListener listener, final DatagramPacket packet) {
	}

	/**
	 * Returns the name of this server.
	 *
	 * @return the name of this server.
	 */
	public String getName() {
		return fName;
	}

	/**
	 * Returns the description of this server.
	 *
	 * @return the description of this server.
	 */
	public String getDescription() {
		return fDescription;
	}

	/**
	 * Returns an ArrayList with this server's tcp listeners. The ArrayList elements
	 * are UDPListener classes.
	 *
	 * @return ArrayList with this server's udp listeners.
	 */
	public ArrayList<UDPListener> getListeners() {
		return fListeners;
	}

	/**
	 * Returns the total bytes received from this server.
	 *
	 * @return the total bytes received from this server.
	 */
	public long getBytesIn() {
		long bytesIn = 0;
		try {
			for (int i = 0; i < fListeners.size(); i++) {
				try {
					bytesIn += ((UDPListener) fListeners.get(i)).getBytesIn();
				} catch (Exception ex) {
				}
			}
		} catch (Exception ex) {
		}
		return bytesIn;
	}

	/**
	 * Returns the total bytes send from this server.
	 *
	 * @return the total bytes send from this server.
	 */
	public long getBytesOut() {
		long bytesOut = 0;
		try {
			for (int i = 0; i < fListeners.size(); i++) {
				try {
					bytesOut += ((UDPListener) fListeners.get(i)).getBytesOut();
				} catch (Exception ex) {
				}
			}
		} catch (Exception ex) {
		}
		return bytesOut;
	}
}
